<template>
  <div class="resource-manage">
    <div class="header">
      <div class="header-btn">
        <el-button type="primary" @click="showCreateDialog" :icon="Plus">上传资源</el-button>
      </div>
      <div class="header-select">
        <el-select v-model="filterCategory" placeholder="按分类过滤" clearable @change="fetchFilteredResources">
          <el-option label="文档" value="DOCUMENT"></el-option>
          <el-option label="视频" value="VIDEO"></el-option>
          <el-option label="音频" value="AUDIO"></el-option>
          <el-option label="图片" value="IMAGE"></el-option>
        </el-select>
      </div>
    </div>
    <el-table :data="resourceStore.resources" style="width: 100%">
      <el-table-column prop="id" label="ID" width="80"></el-table-column>
      <el-table-column prop="title" label="标题" show-overflow-tooltip></el-table-column>
      <el-table-column prop="category" label="分类" width="120">
        <template #default="{ row }">
          {{ categoryMap[row.category] || row.category }}
        </template>
      </el-table-column>
      <el-table-column prop="fileUri" label="文件名" show-overflow-tooltip>
        <template #default="{ row }">
          {{ row.fileUri.split('/').pop() || row.fileUri }}
        </template>
      </el-table-column>
      <el-table-column prop="fileType" label="文件类型" width="120"></el-table-column>
      <el-table-column prop="fileSize" label="文件大小" width="120">
        <template #default="{ row }">
          {{ formatFileSize(row.fileSize) }}
        </template>
      </el-table-column>
      <el-table-column prop="uploadTime" label="上传时间" width="180">
        <template #default="{ row }">
          {{ formatTime(row.uploadTime) }}
        </template>
      </el-table-column>
      <el-table-column label="操作" width="350">
        <template #default="{ row }">
          <el-button type="primary" size="small" @click="showEditDialog(row)" :icon="Edit">修改</el-button>
          <el-button type="info" size="small" @click="viewResource(row)" :icon="View">查看</el-button>
          <el-button type="success" size="small" @click="downloadResource(row)" :icon="Download">下载</el-button>
          <el-button type="danger" size="small" @click="resourceStore.deleteResource(row.id)" :icon="Delete">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 上传资源对话框 -->
    <el-dialog title="上传资源" v-model="createDialogVisible" width="40%">
      <el-form :model="createForm" label-width="80px" :rules="formRules" ref="createFormRef">
        <el-form-item label="标题" prop="title">
          <el-input v-model="createForm.title"></el-input>
        </el-form-item>
        <el-form-item label="分类" prop="category">
          <el-select v-model="createForm.category" placeholder="请选择分类">
            <el-option label="文档" value="DOCUMENT"></el-option>
            <el-option label="视频" value="VIDEO"></el-option>
            <el-option label="音频" value="AUDIO"></el-option>
            <el-option label="图片" value="IMAGE"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="文件" prop="file">
          <el-upload
            :auto-upload="false"
            :limit="1"
            :on-change="handleFileChange"
            :file-list="createFileList"
            accept=".pdf,.mp4,.mp3,.jpg,.jpeg,.png,.txt"
          >
            <el-button type="primary">选择文件</el-button>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="createDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="createResource" :icon="Plus">确定</el-button>
      </template>
    </el-dialog>

    <!-- 修改资源对话框 -->
    <el-dialog title="修改资源" v-model="editDialogVisible" width="40%">
      <el-form :model="editForm" label-width="80px" :rules="formRules" ref="editFormRef">
        <el-form-item label="标题" prop="title">
          <el-input v-model="editForm.title"></el-input>
        </el-form-item>
        <el-form-item label="分类" prop="category">
          <el-select v-model="editForm.category" placeholder="请选择分类">
            <el-option label="文档" value="DOCUMENT"></el-option>
            <el-option label="视频" value="VIDEO"></el-option>
            <el-option label="音频" value="AUDIO"></el-option>
            <el-option label="图片" value="IMAGE"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="文件">
          <el-upload
            :auto-upload="false"
            :limit="1"
            :on-change="handleEditFileChange"
            :file-list="editFileList"
            accept=".pdf,.mp4,.mp3,.jpg,.jpeg,.png,.txt"
          >
            <el-button type="primary">替换文件</el-button>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="editDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="updateResource" :icon="Edit">确定</el-button>
      </template>
    </el-dialog>

    <!-- 查看资源对话框 -->
    <el-dialog :title="viewResourceData.title" v-model="viewDialogVisible" width="60%">
      <div class="resource-preview">
        <img v-if="isImage(viewResourceData.fileType)" :src="fileUrl" alt="资源预览" @error="handleFileError" />
        <video v-else-if="isVideo(viewResourceData.fileType)" controls :src="fileUrl" @error="handleFileError">
          <source :src="fileUrl" :type="getVideoMimeType(viewResourceData.fileType)">
        </video>
        <audio v-else-if="isAudio(viewResourceData.fileType)" controls :src="fileUrl" @error="handleFileError">
          <source :src="fileUrl" :type="getAudioMimeType(viewResourceData.fileType)">
        </audio>
        <iframe v-else-if="isPdf(viewResourceData.fileType)" :src="fileUrl" width="100%" height="500px"></iframe>
        <pre v-else-if="isText(viewResourceData.fileType)" class="text-preview">{{ textContent }}</pre>
        <p v-else>暂不支持该文件类型预览，请下载查看。</p>
      </div>
      <template #footer>
        <el-button @click="viewDialogVisible = false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { Plus, Edit, Delete, View, Download } from '@element-plus/icons-vue';
import { useResourceStore, Resource, ResourceCreateRequest, ResourceUpdateRequest } from '@/stores/api/resource';
import { ElMessage, type FormInstance, type FormRules, type UploadFile } from 'element-plus';
import { fetchFile, downloadFile } from '@/stores/util/file';

const resourceStore = useResourceStore();

const categoryMap = {
  DOCUMENT: '文档',
  VIDEO: '视频',
  AUDIO: '音频',
  IMAGE: '图片',
};

const createDialogVisible = ref(false);
const editDialogVisible = ref(false);
const viewDialogVisible = ref(false);
const filterCategory = ref('');
const fileUrl = ref('');
const textContent = ref('');

const createForm = ref<ResourceCreateRequest>({
  title: '',
  category: 'DOCUMENT',
  file: null as any,
});

const editForm = ref<ResourceUpdateRequest>({
  id: 0,
  title: '',
  category: 'DOCUMENT',
  file: null as any,
});

const viewResourceData = ref<Resource>({
  id: 0,
  title: '',
  category: 'DOCUMENT',
  fileType: '',
  fileSize: 0,
  fileUri: '',
  uploadTime: '',
});

const createFileList = ref<UploadFile[]>([]);
const editFileList = ref<UploadFile[]>([]);

const formRules = ref<FormRules>({
  title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
  category: [{ required: true, message: '请选择分类', trigger: 'change' }],
  file: [
    {
      validator: (rule: any, value: any, callback: any) => {
        if (!createForm.value.file) {
          callback(new Error('请选择文件'));
        } else {
          callback();
        }
      },
      trigger: 'change',
    },
  ],
});

const createFormRef = ref<FormInstance>();
const editFormRef = ref<FormInstance>();

const formatFileSize = (bytes: number) => {
  if (bytes < 1024) return bytes + ' B';
  if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB';
  return (bytes / (1024 * 1024)).toFixed(2) + ' MB';
};

const formatTime = (time: string) => {
  if (!time) return '-';
  const date = new Date(time);
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
  });
};

const isImage = (fileType: string) => ['jpg', 'jpeg', 'png', 'gif'].includes(fileType?.toLowerCase?.());
const isVideo = (fileType: string) => ['mp4', 'webm', 'ogg'].includes(fileType?.toLowerCase?.());
const isAudio = (fileType: string) => ['mp3', 'wav', 'ogg'].includes(fileType?.toLowerCase?.());
const isPdf = (fileType: string) => ['pdf'].includes(fileType?.toLowerCase?.());
const isText = (fileType: string) => ['txt', 'text/plain'].includes(fileType?.toLowerCase?.());

const getVideoMimeType = (fileType: string) => {
  const type = fileType?.toLowerCase?.();
  return type === 'mp4' ? 'video/mp4' : type === 'webm' ? 'video/webm' : 'video/ogg';
};

const getAudioMimeType = (fileType: string) => {
  const type = fileType?.toLowerCase?.();
  return type === 'mp3' ? 'audio/mpeg' : type === 'wav' ? 'audio/wav' : 'audio/ogg';
};

const handleFileError = () => {
  ElMessage.error('文件加载失败');
  fileUrl.value = '';
  textContent.value = '无法预览文件内容';
};

const handleFileChange = (file: UploadFile) => {
  createForm.value.file = file.raw;
  createFileList.value = [file];
};

const handleEditFileChange = (file: UploadFile) => {
  editForm.value.file = file.raw;
  editFileList.value = [file];
};

const showCreateDialog = () => {
  createForm.value = { title: '', category: 'DOCUMENT', file: null as any };
  createFileList.value = [];
  createDialogVisible.value = true;
};

const showEditDialog = (resource: Resource) => {
  editForm.value = { id: resource.id, title: resource.title, category: resource.category, file: null as any };
  editFileList.value = [];
  editDialogVisible.value = true;
};

const viewResource = async (resource: Resource) => {
  viewResourceData.value = resource;
  try {
    if (isText(resource.fileType)) {
      textContent.value = (await fetchFile(resource.fileUri, 'text')) as string;
    } else {
      if (fileUrl.value) {
        URL.revokeObjectURL(fileUrl.value);
      }
      fileUrl.value = (await fetchFile(resource.fileUri, 'blob')) as string;
    }
    viewDialogVisible.value = true;
  } catch (error) {
    handleFileError();
  }
};

const downloadResource = async (resource: Resource) => {
  try {
    await downloadFile(resource.fileUri, resource.title);
  } catch (error) {
    ElMessage.error('下载文件失败');
  }
};

const createResource = async () => {
  if (!createFormRef.value) return;
  createFormRef.value.validate(async (valid) => {
    if (valid) {
      if (!createForm.value.file || !(createForm.value.file instanceof File)) {
        ElMessage.error('请选择有效文件');
        return;
      }
      try {
        await resourceStore.createResource(createForm.value);
        createDialogVisible.value = false;
        await fetchFilteredResources();
      } catch (error) {
        // 错误已在 store 中处理
      }
    }
  });
};

const updateResource = async () => {
  if (!editFormRef.value) return;
  editFormRef.value.validate(async (valid) => {
    if (valid) {
      if (editForm.value.file && !(editForm.value.file instanceof File)) {
        ElMessage.error('请选择有效文件');
        return;
      }
      try {
        await resourceStore.updateResource(editForm.value);
        editDialogVisible.value = false;
        await fetchFilteredResources();
      } catch (error) {
        // 错误已在 store 中处理
      }
    }
  });
};

const fetchFilteredResources = async () => {
  try {
    if (filterCategory.value) {
      resourceStore.resources = (await resourceStore.fetchResourcesByCategory(filterCategory.value)) || [];
    } else {
      await resourceStore.fetchResources();
    }
  } catch (error) {
    // 错误已在 store 中处理
  }
};

onMounted(() => {
  fetchFilteredResources();
});

onUnmounted(() => {
  if (fileUrl.value) {
    URL.revokeObjectURL(fileUrl.value);
  }
});
</script>

<style scoped>
.resource-manage {
  padding: 20px;
}

.header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 20px;
}

.resource-preview {
  text-align: center;
}

.resource-preview img {
  max-width: 100%;
  max-height: 500px;
}

.resource-preview video,
.resource-preview audio {
  width: 100%;
}

.resource-preview .text-preview {
  white-space: pre-wrap;
  text-align: left;
  max-height: 500px;
  overflow-y: auto;
  padding: 10px;
  border: 1px solid #e8e8e8;
  background-color: #f9f9f9;
}
</style>